using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using PioneerBoilerplate.Model.Admin;
using PioneerBoilerplate.Repository;
using PioneerBoilerplate.Repository.Repositories;
using PioneerBoilerplate.Service.Admin.LoginLog.Input;
using PioneerBoilerplate.Service.Admin.LoginLog.Output;
using PioneerBoilerplate.Service.Base;
using PioneerBoilerplate.Util;
using PioneerBoilerplate.Util.Helpers;
using PioneerBoilerplate.Util.Input;
using PioneerBoilerplate.Util.Output;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace PioneerBoilerplate.Service.Admin.LoginLog
{
    public class LoginLogService : BaseService, ILoginLogService
    {
        private readonly IHttpContextAccessor _context;
        private readonly ILoginLogRepository _loginLogRepository;

        public LoginLogService(
            IHttpContextAccessor context,
            ILoginLogRepository loginLogRepository
        )
        {
            _context = context;
            _loginLogRepository = loginLogRepository;
        }

        public async Task<IResponseOutput> PageAsync(PageInput<LoginLogEntity> input)
        {
            var userName = input.Filter?.CreatedUserName;

            PaginationSpecification<LoginLogEntity> specification = new();
            specification.WhereIf(userName.NotNull(), e => e.CreatedUserName.Contains(userName));
            specification.OrderBy = q => q.OrderBy(e => e.Id);
            specification.PageIndex = input.CurrentPage;
            specification.PageSize = input.PageSize;

            var list = await _loginLogRepository.GetListAsync(specification);
            var data = new PageOutput<LoginLogEntity>()
            {
                List = Mapper.Map<List<LoginLogEntity>>(list.Items),
                Total = list.TotalItems
            };

            return ResponseOutput.Ok(data);
        }

        public async Task<IResponseOutput<long>> AddAsync(LoginLogAddInput input)
        {
            var res = new ResponseOutput<long>();

            input.IP = IPHelper.GetIP(_context?.HttpContext?.Request);

            string ua = _context.HttpContext.Request.Headers["User-Agent"];
            if (ua.NotNull())
            {
                var client = UAParser.Parser.GetDefault().Parse(ua);
                var device = client.Device.Family;
                device = device.ToLower() == "other" ? "" : device;
                input.Browser = client.UA.Family;
                input.Os = client.OS.Family;
                input.Device = device;
                input.BrowserInfo = ua;
            }
            var entity = Mapper.Map<LoginLogEntity>(input);
            var id = (await _loginLogRepository.InsertAsync(entity)).Id;

            return id > 0 ? res.Ok(id) : res;
        }
    }
}